package com.easytouch.core.utils;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;

/**
 * Created by gulin on 2017/7/17.
 */

public class Tools {

    /**
     * 从byte数组中，从begin开始到end-1的byte，放到一个新的byte数组里
     *
     * @param b
     * @param begin
     * @param end
     * @return
     */
    public static byte[] subByte(byte[] b, int begin, int end) {
        int len = end - begin;
        byte[] ret = new byte[len];
        for (int i = 0; i < len; i++)
            ret[i] = b[begin + i];
        return ret;
    }

    public static byte[] mergeByte(byte[] b1, byte[] b2) {
        if (b1 == null)
            return b2;
        if (b2 == null)
            return b1;
        int b1Len = b1.length;
        int b2Len = b2.length;
        byte[] ret = new byte[b1Len + b2Len];
        System.arraycopy(b1, 0, ret, 0, b1Len);
        System.arraycopy(b2, 0, ret, b1Len, b2Len);
        return ret;
    }

    /**
     * bytesToHexString 转为16进制，一个byte转两个
     * @param src
     * @return String
     * @since V1.0
     */
    public static String bytesToHexString(byte[] src) {
        StringBuilder stringBuilder = new StringBuilder("");
        if (src == null)
            return null;
        int len = src.length;
        if (src == null || len <= 0) {
            return null;
        }
        for (int i = 0; i < len; i++) {
            int v = src[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString().toUpperCase(Locale.US);
    }

    /**
     * 转为2位的16进制
     *
     * @param src
     * @return
     */
    public static String bytesToHexString(byte src) {

        StringBuilder stringBuilder = new StringBuilder("");
        int v = src & 0xFF;
        String hv = Integer.toHexString(v);
        if (hv.length() < 2) {
            stringBuilder.append(0);
        }
        stringBuilder.append(hv);

        return stringBuilder.toString().toUpperCase(Locale.US);
    }

    /**
     * @Title: hexStringToBytes
     * @Description:
     *
     * @param hexString
     * @return byte[]
     * @since V1.0
     */
    public static byte[] hexStringToBytes(String hexString) {
        if (hexString == null || hexString.equals("")) {
            return null;
        }
        hexString = hexString.toUpperCase(Locale.US);
        int srcLength = hexString.length();
        int mod = srcLength % 2;
        if (mod != 0) {
            srcLength++;
            hexString = addLeftZero(hexString, srcLength);
        }
        int length = (srcLength) / 2;
        char[] hexChars = hexString.toCharArray();
        byte[] d = new byte[length];
        for (int i = 0; i < length; i++) {
            int pos = i * 2;
            d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
        }
        return d;
    }

    /**
     * @Title: charToByte
     * @Description:
     *
     * @param c
     * @return byte
     * @since V1.0
     */
    public static byte charToByte(char c) {
        return (byte) "0123456789ABCDEF".indexOf(c);
    }

    /**
     * @Title: 每一位bytesToHexString
     * @Description:
     *
     * @param src
     * @return String
     * @since V1.0
     */
    public static String bytesToBinaryString(byte[] src) {

        int len = src.length;
        if (src == null || len <= 0) {
            return null;
        }
        StringBuilder stringBuilder = new StringBuilder("");
        for (int i = 0; i < len; i++) {
            int v = src[i] & 0xFF;
            String hv = Integer.toBinaryString(v);
            stringBuilder.append(addLeftZero(hv, 8));
        }
        return stringBuilder.toString();
    }

    /**
     * 单个byte转换为8位二进制字符串
     *
     * @param src
     * @return
     */
    public static String bytesToBinaryString(byte src) {

        StringBuilder stringBuilder = new StringBuilder("");
        int v = src & 0xFF;
        String hv = Integer.toBinaryString(v); // 不一定返8�?
        stringBuilder.append(addLeftZero(hv, 8));
        return stringBuilder.toString();
    }

    /**
     * @Title: binaryStringToBytes
     * @Description:
     *
     * @param binaryString
     * @return byte[]
     * @since V1.0
     */
    public static byte[] binaryStringToBytes(String binaryString) {
        if (binaryString == null || binaryString.equals("")) {
            return null;
        }
        int length = binaryString.length() / 8;
        byte[] d = new byte[length];
        for (int i = 0; i < length; i++) {
            d[i] = (byte) Integer.parseInt(
                    binaryString.substring(i * 8, (i + 1) * 8), 2);
        }
        return d;
    }

    /**
     * 将byte数组转为十进制数
     *
     * @param src
     * @return
     */
    public static String bytesToBcdString(byte[] src) {

        int len = src.length;
        if (src == null || len <= 0) {
            return null;
        }

        StringBuilder stringBuilder = new StringBuilder("");
        for (int i = 0; i < len; i++) {
            int v = src[i] & 0xFF;
            String hv = addLeftZero(Integer.toBinaryString(v), 8);
            stringBuilder.append(String.valueOf(Integer.parseInt(
                    hv.substring(0, 4), 2)));
            stringBuilder.append(String.valueOf(Integer.parseInt(
                    hv.substring(4, 8), 2)));
        }
        return stringBuilder.toString();
    }

    /**
     * 将单个byte数组转为十进制数
     *
     * @param src
     * @return
     */
    public static String bytesToBcdString(byte src) {
        StringBuilder stringBuilder = new StringBuilder("");
        int v = src & 0xFF;
        String hv = addLeftZero(Integer.toBinaryString(v), 8);
        stringBuilder.append(String.valueOf(Integer.parseInt(
                hv.substring(0, 4), 2)));
        stringBuilder.append(String.valueOf(Integer.parseInt(
                hv.substring(4, 8), 2)));
        return stringBuilder.toString();
    }

    /**
     * 2位转1�??
     *
     * @param bcdString
     * @return
     */
    public static byte[] bcdStringToBytes(String bcdString) {
        if (bcdString == null || bcdString.equals("")) {
            return null;
        }
        int length = bcdString.length() / 2;
        byte[] d = new byte[length];
        for (int i = 0; i < length; i++) {
            int index = i * 2;
            String aPart = bcdString.substring(index, index + 1);
            String bPart = bcdString.substring(index + 1, index + 2);
            String aPartBinaryStr = bytesToBinaryString(
                    new byte[] { (byte) Integer.parseInt(aPart) }).substring(4);
            String bPartBinaryStr = bytesToBinaryString(
                    new byte[] { (byte) Integer.parseInt(bPart) }).substring(4);
            String binaryStr = aPartBinaryStr + bPartBinaryStr;
            d[i] = binaryStringToBytes(binaryStr)[0];
        }
        return d;
    }

    public static byte[] fillByteLen(byte[] ret, int len) {
        byte[] subbyte = null;

        if (ret != null && len < ret.length) {
            return subByte(ret, 0, len);
        }

        try {
            if (ret != null) {
                subbyte = new byte[len - ret.length];
            } else {
                subbyte = new byte[len];
            }

            for (int i = 0; i < subbyte.length; i++) {
                subbyte[i] = 0x20;
            }

            ret = mergeByte(ret, subbyte);
        } catch (Exception e) {
        }
        return ret;
    }

    /**
     * 将带符号的字符串形式的整数，转为带符号的二进制数
     *
     * @param src
     * @return
     */
    public static String intToBinaryString(String src) {
        if (src.length() != 3) {
            throw new RuntimeException();
        }
        String sign = src.substring(0, 1);
        String firstBit = "0";
        if ("+".equals(sign)) {
            firstBit = "0";
        } else {
            firstBit = "1";
        }
        String des = Integer.toBinaryString(Integer.parseInt(src.substring(1)));
        if (des.length() < 7) {
            des = addLeftZero(des, 7);
        } else {
            des = des.substring(des.length() - 7, des.length());
        }
        return firstBit + des;
    }

    /**
     * 无符号数
     *
     * @param src
     * @return
     */
    public static String intArrayToBinaryString(Integer[] src) {
        if (src == null)
            return "";
        StringBuilder bStr = new StringBuilder();
        int len = src.length;
        for (int i = 0; i < len; i++) {
            String des = Integer.toBinaryString(src[i]);
            bStr.append(addLeftZero(des, 16));
        }
        return bStr.toString();
    }

    public static String hexToBinaryString(String src) {
        try {
            int i = Integer.parseInt(src, 16);
            return Integer.toBinaryString(i);

        } catch (NumberFormatException e) {
            e.printStackTrace();
            return "";
        }
    }

    public static long bytesToLong(byte[] data) {
        return Long.parseLong(bytesToBinaryString(data), 2);
    }

    public static long bytesToLong(byte data) {
        return Long.parseLong(bytesToBinaryString(data), 2);
    }

    public static int bytesToInt(byte[] data) {
        return Integer.parseInt(bytesToBinaryString(data), 2);
    }

    public static int bytesToInt(byte data) {
        return Integer.parseInt(bytesToBinaryString(data), 2);
    }

    public static String getCurrentDate() {
        SimpleDateFormat sd = new SimpleDateFormat("yyyyMMdd", Locale.US);
        return sd.format(new Date());
    }

    public static String getYesterday() {
        Calendar ca = new GregorianCalendar();
        ca.add(Calendar.DAY_OF_MONTH, -1);
        Date d = ca.getTime();
        SimpleDateFormat sd = new SimpleDateFormat("yyyyMMdd", Locale.US);
        return sd.format(d);
    }

    public static String getCurrentTime() {
        SimpleDateFormat sd = new SimpleDateFormat("yyyyMMddHHmmss", Locale.US);
        return sd.format(new Date());
    }

    public static String getFullCurrentTime() {
        SimpleDateFormat sd = new SimpleDateFormat("yyyyMMddHHmmssSSS",
                Locale.US);
        return sd.format(new Date());
    }

    public static String getTime() {
        SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS",
                Locale.US);
        return sd.format(new Date());
    }

    public static String getShortTime() {
        SimpleDateFormat sd = new SimpleDateFormat("yyyyMMdd", Locale.US);
        return sd.format(new Date());
    }

    public static String nullToStr(String s) {
        return (s == null) ? "" : s.trim();
    }

    public static boolean checkDigit(String str) {
        for (int i = 0; i < str.length(); i++) {
            if (!Character.isDigit(str.charAt(i))) {
                return false;
            }
        }
        return true;
    }

    public static boolean isDateTime(String str) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss",
                Locale.US);
        try {
            formatter.parse(str);
        } catch (Exception e) {
            return false;
        }
        return true;
    }

    /**
     * 如果src的长度不够len的话，就在src的左边补0，否则直接返回src
     *
     * @param src
     * @param len
     * @return
     */
    public static String addLeftZero(String src, int len) {

        int sLen = src.length();

        if (sLen >= len) {
            return src;
        }
        return String.format("%0" + (len - sLen) + "d", 0) + src;
    }

    public static String addLeftOrRightStr(String dir, String add, String src,
                                           int len) {

        int sLength = src.length();

        if (sLength > len) {
            return src.substring(0, len);
        }
        StringBuffer tmpStr = new StringBuffer();
        int offsetLen = len - sLength;
        if ("L".equals(dir)) {
            for (int i = 0; i < offsetLen; i++) {
                tmpStr.append(add);
            }
            tmpStr.append(src);
            return tmpStr.toString();
        } else {
            tmpStr.append(src);
            for (int i = 0; i < offsetLen; i++) {
                tmpStr.append(add);
            }
            return tmpStr.toString();
        }
    }

    public static int length(String value) {
        int valueLength = 0;
        String chinese = "[\u0391-\uFFE5]";
        for (int i = 0; i < value.length(); i++) {
            String temp = value.substring(i, i + 1);
            if (temp.matches(chinese)) {
                valueLength += 2;
            } else {
                valueLength += 1;
            }
        }
        return valueLength;
    }

    /**
     * 设置价格形式，保留两位小数
     *
     * @param price
     *            以分为单位的价格
     * @return 两位小数价格
     */
    public static String priceFormat(String price) {
        // double price = ;
        String fPrice = String.valueOf(Integer.parseInt(price) / 100.0);
        int index = fPrice.indexOf(".");
        String p = fPrice.substring(index);
        if (p.length() >= 3)
            return fPrice.substring(0, index + 3);
        else
            return fPrice + String.format("%0" + (3 - p.length()) + "d", 0);
    }

    public static String priceFormat(double price) {
        // double price = ;
        String fPrice = String.valueOf(price);
        int index = fPrice.indexOf(".");
        String p = fPrice.substring(index);
        if (p.length() >= 3)
            return fPrice.substring(0, index + 3);
        else
            return fPrice + String.format("%0" + (3 - p.length()) + "d", 0);
    }

    //定位相关方法
    private static final double EARTH_RADIUS = 6378137;

    private static double rad(double d) {
        return d * Math.PI / 180.0;
    }

    /**
     * 根据两点间经纬度坐标（double值），计算两点间距离，单位为米
     *
     * @param lng1
     * @param lat1
     * @param lng2
     * @param lat2
     * @return
     */
    public static double GetDistance(double lng1, double lat1, double lng2,
                                     double lat2) {
        double radLat1 = rad(lat1);
        double radLat2 = rad(lat2);
        double a = radLat1 - radLat2;
        double b = rad(lng1) - rad(lng2);
        double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2)
                + Math.cos(radLat1) * Math.cos(radLat2)
                * Math.pow(Math.sin(b / 2), 2)));
        s = s * EARTH_RADIUS;
        s = Math.round(s * 10000) / 10000;
        return s;
    }
}
